package dispatcher

import (
	"gitee.com/hasika/common-server/codec"
	"gitee.com/hasika/common-server/conn/inet"
	"gitee.com/hasika/common-server/idispatcher"
	"gitee.com/hasika/common-server/option"
	"gitee.com/hasika/common-server/session"
)

type MessageFunc func(data codec.Packet, conn inet.Conn)

func NewDefaultDispatcher(opt *option.ServiceOption, manager *session.Manager) idispatcher.MessageDispatcher {
	mixedRouter := option.NewProtoMessageRouter()
	for _, oneRouter := range opt.Routers() {
		mixedRouter.Merge(oneRouter)
	}
	mixedRouter.Merge(manager.GetRouter())
	fallbackHandler := opt.GetFallbackHandler()
	cmdDispatcher := NewProtoMessageDispatcher(mixedRouter, manager)
	return NewMultiDispatcher(manager.ApplySessionData, func(data codec.Packet, conn inet.Conn) {
		if cmdDispatcher.CanHandle(data, conn) {
			cmdDispatcher.DispatchMessage(data, conn)
		} else {
			if fallbackHandler != nil {
				fallbackHandler(data, conn)
			} else {
				message := data.GetMessage()
				if message != nil {
					Log.Errorf("can't handle message %+v", message.ProtoReflect().Descriptor().FullName())
				}
			}
		}
	})
}
